package com.itranswarp.learnjava.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

// @Autowired的作用是自动装配，它可以自动装配Bean，
// 装配的规则是：如果容器中只有一个Bean，那么就装配这个Bean，
// 如果容器中多个Bean，那么就装配名称和字段名相同的Bean。
// @Autowired就相当于把指定类型的Bean注入到指定的字段中。

@Component
public class UserService {
    // 为什么要使用@Autowired注解？因为UserService需要使用MailService，
    // 所以我们需要在UserService中定义一个MailService的字段，
    // 然后在UserService的构造函数中传入一个MailService的实例，这样才能使用UserService。
    // 但是这样写起来比较麻烦，所以我们可以使用@Autowired注解，这样就可以自动注入了。
    // 但是如果我们不使用@Autowired注解，那么就需要在UserService的构造函数中传入一个MailService的实例，
    // 这样才能使用UserService。
    // 但是如果我们不使用@Autowired注解，那么就需要在UserService的构造函数中传入一个MailService的实例，

    // - @Autowired 注解告诉Spring容器：这个字段需要自动注入一个类型为 MailService 的Bean
    // 当Spring容器初始化 UserService 这个Bean时，会查找容器中类型为 MailService 的Bean
    // 找到后，Spring会自动将该Bean的实例注入到这个字段中
    @Autowired
    MailService mailService;

    public UserService(@Autowired MailService mailService) {
        this.mailService = mailService;
    }

    private List<User> users = new ArrayList<>(List.of( // users:
            new User(1, "bob@example.com", "password", "Bob"), // bob
            new User(2, "alice@example.com", "password", "Alice"), // alice
            new User(3, "tom@example.com", "password", "Tom"))); // tom

    public User login(String email, String password) {
        for (User user : users) {
            if (user.getEmail().equalsIgnoreCase(email) && user.getPassword().equals(password)) {
                mailService.sendLoginMail(user);
                return user;
            }
        }
        throw new RuntimeException("login failed.");
    }

    public User getUser(long id) {
        return this.users.stream().filter(user -> user.getId() == id).findFirst().orElseThrow();
    }

    public User register(String email, String password, String name) {
        users.forEach((user) -> {
            if (user.getEmail().equalsIgnoreCase(email)) {
                throw new RuntimeException("email exist.");
            }
        });
        User user = new User(users.stream().mapToLong(u -> u.getId()).max().getAsLong(), email, password, name);
        users.add(user);
        mailService.sendRegistrationMail(user);
        return user;
    }
}
